package fct.mpc.snipehunter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import fct.mpc.utils.HuntingGrounds;
import fct.mpc.utils.SnipeCollection;
import fct.mpc.utils.StatManager;

public class SnipeHunterMenuActivity extends ListActivity {
	private ProgressDialog progressDialog;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		new LoadAssetsTask().execute();
		
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	}
	
	@Override
	protected void onDestroy()
	{
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		
		super.onDestroy();
	}

	@Override
	public void onBackPressed() {
		new SaveAssetsTask().execute();

		super.onBackPressed();
	}

	protected List<Map<String, ?>> getData()
	{
		List<Map<String, ?>> data = new ArrayList<Map<String, ?>>();

		Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
		mainIntent.addCategory(Intent.CATEGORY_DEFAULT);

		PackageManager pm = getPackageManager();
		List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);

		if (null == list)
			return data;

		int len = list.size();

		for (int i = 0; i < len; i++) {
			ResolveInfo info = list.get(i);

			CharSequence labelSeq = info.loadLabel(pm);

			if ("fct.mpc.snipehunter"
					.equals(info.activityInfo.applicationInfo.packageName))
				addItem(data,
						labelSeq.toString(),
						activityIntent(
								info.activityInfo.applicationInfo.packageName,
								info.activityInfo.name));
		}

		return data;
	}

	protected void addItem(List<Map<String, ?>> data, String name, Intent intent)
	{
		Map<String, Object> temp = new HashMap<String, Object>();

		temp.put("title", name);
		temp.put("intent", intent);
		data.add(temp);
	}

	protected Intent activityIntent(String pkg, String componentName)
	{
		Intent result = new Intent();
		result.setClassName(pkg, componentName);
		return result;
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Map<?, ?> map = (Map<?, ?>) l.getItemAtPosition(position);

		Intent intent = (Intent) map.get("intent");
		startActivity(intent);
	}

	private class LoadAssetsTask extends AsyncTask<Void, Integer, Void> {
		@Override
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(SnipeHunterMenuActivity.this,
					"Loading...", "Loading application, please wait...", false,
					false);
		}

		@Override
		protected Void doInBackground(Void... params) {
			synchronized (this) {
				AssetManager assetManager = getAssets();

				try 
				{
					if (!HuntingGrounds.hasHuntingGrounds())
						HuntingGrounds.populateHuntingGrounds(assetManager.open("hunting_grounds.xml"));

					// Snipes collection
					if (!SnipeCollection.hasSnipes()) {
						File dir = new File(getFilesDir(), "internal");
						if (dir.exists()) {
							File file = new File(dir, "snipes_collection.xml");
							if (!file.exists())
								SnipeCollection
										.populateSnipeCollectionByAsset(assetManager
												.open("snipes_list.xml"));
							else {
								FileInputStream fis = new FileInputStream(file);
								InputStream is = (InputStream) fis;
								SnipeCollection
										.populateSnipeCollectionByXML(is);
							}
						} else
							SnipeCollection
									.populateSnipeCollectionByAsset(assetManager
											.open("snipes_list.xml"));
					}

					// Stats
					if (!StatManager.hasStats()) {
						File dir = new File(getFilesDir(), "internal");
						if (dir.exists()) {
							File file = new File(dir, "stats.xml");
							if (!file.exists())
								StatManager
										.populateStatManagerByAsset(assetManager
												.open("stats_list.xml"));
							else {
								FileInputStream fis = new FileInputStream(file);
								InputStream is = (InputStream) fis;
								StatManager.populateStatManagerByXML(is);
							}
						} else
							StatManager.populateStatManagerByAsset(assetManager
									.open("stats_list.xml"));
					}

				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			progressDialog.dismiss();

			setListAdapter(new SimpleAdapter(SnipeHunterMenuActivity.this,
					getData(), android.R.layout.simple_list_item_1,
					new String[] { "title" }, new int[] { android.R.id.text1 }));
			getListView().setTextFilterEnabled(true);
		}
	}

	private class SaveAssetsTask extends AsyncTask<Void, Integer, Void> {
		@Override
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(SnipeHunterMenuActivity.this,
					"Exiting...",
					"Saving snipes and stats data, please wait...", false,
					false);
		}

		@Override
		protected Void doInBackground(Void... params) {
			File path = new File(getFilesDir(), "internal");
			if (!path.exists())
				path.mkdir();

			File fileSnipes = new File(path, "snipes_collection.xml");
			File fileStats = new File(path, "stats.xml");
			try {
				// Snipes
				fileSnipes.delete();
				fileSnipes.createNewFile();

				BufferedWriter bw = new BufferedWriter(new FileWriter(
						fileSnipes));

				SnipeCollection.writeSnipeCollectionAsXML(bw);

				// Stats
				fileStats.delete();
				fileStats.createNewFile();

				bw = new BufferedWriter(new FileWriter(fileStats));

				StatManager.writeStatManagerAsXML(bw);

			} catch (FileNotFoundException e) {
				throw new RuntimeException(e);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}

			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			progressDialog.dismiss();
		}
	}
}
